import React, { useEffect, useState, useRef } from 'react'
import T from 'prop-types'
import MessageItem from './components/message-item'
import MessageInputBox from './components/message-input-box'
import './index.scss'

function MediationRoom(props) {
  const [messageList, setMessageList] = useState([])
  const [times, setTimes] = useState(0) //实际重连次数
  const messageListRef = useRef()
  const { id, type } = props
  const [scrollInfo, setScrollInfo] = useState({
    preScrollHeight: 0,
    isShowNewMessageTips: false,
  })
  let wsUrl = `ws://localhost:3001/sendMessages?userid=${localStorage.getItem(
    'userid'
  )}`
  // 心跳检测时长60s一次
  const heartBeatTime = 10
  // 如果当前出处页面底部，有接受到新消息时，自动滚动到页面最下面
  const keepMessageListOnBottom = () => {
    const { preScrollHeight } = scrollInfo
    const { clientHeight, scrollTop, scrollHeight } = messageListRef.current
    let isShowNewMessageTips
    if (preScrollHeight - clientHeight - scrollTop < 100) {
      messageListRef.current.scrollTop = scrollHeight
      isShowNewMessageTips = false
    } else {
      isShowNewMessageTips = true
    }
    setScrollInfo({
      preScrollHeight: scrollHeight,
      isShowNewMessageTips: isShowNewMessageTips,
    })
  }
  useEffect(() => {
    // 如果已经在底部，自动出发滚动
    keepMessageListOnBottom()
    // 更新已读进度, messageList变化时,聊天界面会重新渲染, 最后一条数据会到最下边
    messageList.length > 0 &&
      setMessageRead(messageList[messageList.length - 1].id)
  }, [messageList])

  // 回到最新位置
  const renderNewMessageTips = () => {
    const { isShowNewMessageTips } = scrollInfo
    return isShowNewMessageTips ? (
      <div className={'new-message-tips'} onClick={scrollMessageListToBottom}>
        回到最新位置
      </div>
    ) : null
  }
  // 自动滚到到最底部
  const scrollMessageListToBottom = () => {
    const { scrollHeight } = messageListRef.current
    messageListRef.current.scrollTop = scrollHeight
    setScrollInfo({
      preScrollHeight: scrollHeight,
      isShowNewMessageTips: false,
    })
  }
  //  更新已读进度
  const setMessageRead = (latestSeq) => {
    let params = {
      content: '',
      userid: localStorage.getItem('userid'),
      to: id,
      latestSeq: latestSeq,
      type,
      progress: 'updateLatestSeq',
    }
    window.wsServer.send(JSON.stringify(params))
  }
  // 心跳包的设置
  let heartCheck = {
    timeout: heartBeatTime * 1000, //  心跳检测时长
    timeoutObj: null, // 定时变量
    serverTimeoutObj: null,
    reset: function () {
      clearTimeout(this.timeoutObj)
      clearTimeout(this.serverTimeoutObj)
      this.start()
    },
    start: function () {
      let self = this
      this.timeoutObj = setTimeout(function () {
        // 每次ws连接成功时,给服务器发送消息,这样才能获取到最新消息列表
        // 一个心跳包
        const params = { userid: localStorage.getItem('userid'), to: id, type }
        window.wsServer.send(JSON.stringify(params))
        self.serverTimeoutObj = setTimeout(function () {
          console.log('-------长时间服务器无返回，手动关闭ws-----');
          window.wsServer.close() //如果onclose会执行reconnect，我们执行ws.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次
        }, self.timeout)
      }, this.timeout)
    },
  }
  function initEventHandle() {
    window.wsServer.onclose = function (e) {
      //  heartCheck.reset().start()
      console.log('监听到ws被关闭，准备执行重连', e)
      reconnect(wsUrl)
    }
    window.wsServer.onerror = function (err) {
      // heartCheck.reset().start()
      console.log('error')
      reconnect(wsUrl)
    }
    window.wsServer.onopen = function () {
      console.log('连接成功989080')
      // 私聊：连接成功时,发送自己的id和好友id
      // 群聊：发送自己的id和群id
      const params = {
        userid: localStorage.getItem('userid'),
        to: id,
        type,
      }
      window.wsServer.send(JSON.stringify(params))
      heartCheck.start() //心跳检测重置
      console.log(`打开了连接，调用start`)
    }
    window.wsServer.onmessage = function (msg) {
      console.log(window.wsServer)
      //  console.log(JSON.parse(msg.data), '消息')
      setMessageList(JSON.parse(msg.data))
      //如果获取到消息，心跳检测重置
      heartCheck.reset() //拿到任何消息都说明当前连接是正常的
      // console.log('//收到消息，调用reset', JSON.parse(msg.data))
    }
  }
  function reconnect(url) {
    if (reconnect.lockReconnect)
      // 避免触发多次重连
      return
    reconnect.lockReconnect = true
    setTimeout(function () {
      setTimes(times + 1)
      console.log(
        `reconnect开始重连,重连次数为${times}`
      )
      //没连接上会一直重连，设置延迟避免请求过多
      console.log('//没连接上会一直重连，设置延迟避免请求过多')
      createWebSocket(url)
      reconnect.lockReconnect = false
    }, 10000)
  }
  function createWebSocket(url) {
    try {
      if ('WebSocket' in window) {
        // setWsServer(new WebSocket(url))
        window.wsServer = new WebSocket(url)
        console.log(window.wsServer, '新的')
        console.log(`创建新的ws`)
      } else {
        alert('当前浏览器不支持websocket协议,建议使用现代浏览器', 3000)
      }
      initEventHandle()
      console.log('初始化ws')
    } catch (e) {
      console.log('创建失败，开始重连')
      reconnect(url)
    }
  }
  useEffect(() => {
    /**
     * CONNECTING：值为0，表示正在连接；
     * OPEN：值为1，表示连接成功，可以通信了；
     * CLOSING：值为2，表示连接正在关闭；
     * CLOSED：值为3，表示连接已经关闭，或者打开连接失败。
     */
    console.log(window.wsServer, 'window. window.wsServer.readyState')
    if (window.wsServer.readyState === 1) {
      console.log(window.wsServer, '123')
      // 首次进入页面时,注册onopen和onmessage
      initEventHandle()
      // 每次ws连接成功时,给服务器发送消息,这样才能获取到最新消息列表
      const params = { userid: localStorage.getItem('userid'), to: id, type }
      window.wsServer.send(JSON.stringify(params))
    }
    if (window.wsServer.readyState === 3) {
      reconnect(wsUrl)
    }
  }, [window.wsServer.readyState])

  const sendMessage = (data) => {
    let params = {
      content: data && data.value,
      userid: localStorage.getItem('userid'),
      to: id,
      type,
    }
    console.log(window.wsServer)
    window.wsServer.send(JSON.stringify(params))
  }
  const renderMessageList = () => {
    console.log(messageList)
    return messageList.map((item) => {
      return (
        <MessageItem
          key={item.id}
          myProfile={{ userID: localStorage.getItem('userid') }}
          message={item}
          // 消息重新发送, 发送成功后的回调函数
          onResendMessageSuccess={({ data }) => {
            // 更新已读进度
          }}
        />
      )
    })
  }

  return (
    <div className={'current-conversation-wrapper'}>
      <div className={`current-conversation`}>
        <div className={'content'}>
          <div
            ref={messageListRef}
            className={'message-list'}
            id={'message-list'}
          >
            {renderMessageList()}
          </div>
          {renderNewMessageTips()}
        </div>
        <div className={'footer'}>
          <MessageInputBox onMessageSend={(data) => sendMessage(data)} />
        </div>
      </div>
    </div>
  )
}

MediationRoom.propTypes = {
  id: T.string,
  type: T.string,
}
export default MediationRoom
